#ifndef __CACHE_H__
#define __CACHE_H__

#include "common.h"

/* Cache configuration */
#define CACHE_BLOCK_SIZE 64
#define CACHE_SIZE (64 * 1024)
#define CACHE_WAY 8

/* Calculated values */
#define NR_CACHE_BLOCKS (CACHE_SIZE / CACHE_BLOCK_SIZE)
#define NR_CACHE_SETS (NR_CACHE_BLOCKS / CACHE_WAY)

/* Address field widths */
#define BLOCK_OFFSET_BITS 6
#define SET_INDEX_BITS 7
#define TAG_BITS (32 - BLOCK_OFFSET_BITS - SET_INDEX_BITS)

/* Masks */
#define BLOCK_OFFSET_MASK ((1 << BLOCK_OFFSET_BITS) - 1)
#define SET_INDEX_MASK ((1 << SET_INDEX_BITS) - 1)
#define TAG_MASK ((1 << TAG_BITS) - 1)

/* Cache block structure */
typedef struct {
	bool valid;
	uint32_t tag;
	uint8_t data[CACHE_BLOCK_SIZE];
} CacheLine;

/* Cache set structure */
typedef struct {
	CacheLine lines[CACHE_WAY];
} CacheSet;

/* Cache structure */
typedef struct {
	CacheSet sets[NR_CACHE_SETS];
} Cache;

/* Cache operations */
void init_cache();
uint32_t cache_read(hwaddr_t addr, size_t len);
void cache_write(hwaddr_t addr, size_t len, uint32_t data);

#endif

